import type {WL_CoreInterface} from "@/core/weila_datas";
import {WL_ExtEventID} from "@/core/weila_datas";
import {WL} from "@/proto/weilapb";
import {Weila_MemDB} from "@/mem_store/weila_db";
import type {WL_IDbUserInfo} from "@/proto/weilapb_external_data";
import {WeilaPBLoginWrapper} from "@/proto/weilapb_login_wrapper";
import {convertFromUserRaw} from "@/proto/weilapb_utils";
import debug from "debug";

const LLog = debug('LoginLog');

export default class WLLoginModule {
    private account: string;
    private password: string;
    private countryCode: string;

    constructor(private coreInterface: WL_CoreInterface) {
        this.account = '';
        this.password = '';
        this.countryCode = '';
        this.coreInterface.registerPbMsgHandler(WL.Service.ServiceID.SERVICE_LOGIN, this.onPbMsgHandler.bind(this));
    }

    private onPbMsgHandler(data: any): void {
        const serverMessage = data as WL.Service.IServiceMessage;
        const serviceHead = serverMessage.serviceHead;
        if (serverMessage.serviceHead!.commandType == WL.Service.CommandType.COMMAND_RESPONSE) {
            switch (serverMessage.serviceHead!.commandId) {
                case WL.Login.LoginCommandId.LOGIN_COMMAND_LOGIN_APP: {
                    this.coreInterface.rspPbMsg(serviceHead!.seq!, serviceHead!.resultCode!, serverMessage.loginMessage ? serverMessage.loginMessage.rspLoginApp : null);
                }
                break;

                case WL.Login.LoginCommandId.LOGIN_COMMAND_LOGOUT: {
                    this.coreInterface.rspPbMsg(serviceHead!.seq!, serviceHead!.resultCode!, (serviceHead!.resultCode == 0));
                }
                break;

                case WL.Login.LoginCommandId.LOGIN_COMMAND_HEARTBEAT: {
                    LLog('收到心跳响应');
                    this.coreInterface.rspPbMsg(serviceHead!.seq!, serviceHead!.resultCode!, null);
                }
                break;

                case WL.Login.LoginCommandId.LOGIN_COMMAND_GET_EXTENSIONLIST: {
                    this.coreInterface.rspPbMsg(serviceHead!.seq!, serviceHead!.resultCode!, serverMessage.loginMessage ? serverMessage.loginMessage.rspGetExtensionList : null);
                }
                break;

                case WL.Login.LoginCommandId.LOGIN_COMMAND_SET_EXTENSION_CONFIG: {
                    this.coreInterface.rspPbMsg(serviceHead!.seq!, serviceHead!.resultCode!, serverMessage.loginMessage ? serverMessage.loginMessage.rspSetExtensionConfig : null);
                }
                break;
            }
        }else if (serverMessage.serviceHead!.commandType == WL.Service.CommandType.COMMAND_NOTIFY) {
            if (serverMessage.serviceHead!.commandId == WL.Login.LoginCommandId.LOGIN_COMMAND_KICKOUT) {
                LLog("被踢--------------->");
                this.coreInterface.sendExtEvent(WL_ExtEventID.WL_EXT_ACCOUNT_WAS_KICKED_OUT, undefined);
            }
        }
    }

    public saveLoginInfo(account: string, password: string, countryCode: string): void {
        this.account = account;
        this.password = password;
        this.countryCode = countryCode;
    }

    public async loginReq(account: string, password: string, countryCode: string, md5?: boolean): Promise<WL_IDbUserInfo> {
        LLog('========>登录请求: account:%o password:%o countryCode:%o md5:%o', account, password, countryCode, md5);
        // @ts-ignore
        const appId = import.meta.env.APP_ID;
        // @ts-ignore
        const appKey = import.meta.env.APP_KEY;
        const wlBuildMsgRet = WeilaPBLoginWrapper.buildLoginAppReq(account, password, countryCode, appId, appKey, md5);
        if (wlBuildMsgRet.resultCode == 0) {
            try {
                const loginAppRsp = await this.coreInterface.sendPbMsg(wlBuildMsgRet, 10000, true) as WL.Login.IRspLoginApp;

                /**
                 * 把登录返回的信息存入内存区域
                 */
                const dbUserInfo = convertFromUserRaw(loginAppRsp.userInfo);
                Weila_MemDB.getInstance().putLoginToken(loginAppRsp.token!);
                Weila_MemDB.getInstance().putLoginUserInfo(dbUserInfo);
                Weila_MemDB.getInstance().putUser(dbUserInfo);
                LLog("put dbUserInfo %o", dbUserInfo);
                return dbUserInfo;
            }catch (e) {
                return Promise.reject('发送登录消息失败:' + JSON.stringify(e));
            }
        }

        return Promise.reject('创建登录消息失败:' + wlBuildMsgRet.resultCode);
    }

    public async logoutReq(): Promise<boolean> {
        const wlBuildMsgRet = WeilaPBLoginWrapper.buildLogoutReq();
        if (wlBuildMsgRet.resultCode == 0) {
            await this.coreInterface.sendPbMsg(wlBuildMsgRet);
            return true;
        }
        return Promise.reject('创建登出消息失败:' + wlBuildMsgRet.resultCode);
    }

    public async sendHeartbeat(): Promise<boolean> {
        const buildRet = WeilaPBLoginWrapper.buildHeartbeatReq();
        if (buildRet.resultCode == 0) {
            await this.coreInterface.sendPbMsg(buildRet);
            return true;
        }

        return Promise.reject('发送心跳失败');
    }

    public async refreshToken(): Promise<boolean> {
        const buildRet = WeilaPBLoginWrapper.buildRefreshTokenReq();
        if (buildRet.resultCode == 0) {
            const refreshRsp = await this.coreInterface.sendPbMsg(buildRet) as WL.Login.IRspRefreshAccessToken;
            Weila_MemDB.getInstance().putLoginToken(refreshRsp.accessToken!);
            return true;
        }

        return Promise.reject('刷新token失败');
    }
}
